﻿using Microsoft.Practices.EnterpriseLibrary.Data;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TN_CMS.Domain.Abstract;
using TN_CMS.Domain.Entities;
using TN_CMS.Framework.Variable;

namespace TN_CMS.Domain.Concrete
{
    public class EFSysFeatureRepository : BaseRepository, ISysFeatureRepository
    {
        private EFDbContext _context;

        public EFSysFeatureRepository(EFDbContext context = null)
        {
            this._context = (context != null) ? context : new EFDbContext();
        }

        public IQueryable<SysFeature> SysFeatures
        {
            get { return this._context.SysFeatures; }
        }

        public List<SysFeature> GetList(int pageIndex, int pageSize, out int total, string orderClause, string whereClause)
        {
            var map = MapBuilder<SysFeature>
                .MapAllProperties()
                .DoNotMap(m => m.Parent)
                .Map(m => m.ProjectType).WithFunc((row) =>
                {
                    if (row["ProjectType"] != DBNull.Value)
                    {
                        return (EnumProjectType)Convert.ToInt32(row["ProjectType"]);
                    }
                    else
                    {
                        return EnumProjectType.Admin;
                    }
                })
                .Build();
            var parameters = new DbParameter[] { 
                    this._db.CreateParameter("PageIndex", pageIndex, DbType.Int32),
                    this._db.CreateParameter("PageSize", pageSize, DbType.Int32),
                    this._db.CreateParameter("TotalCounts", 0, DbType.Int32, ParameterDirection.Output),
                    this._db.CreateParameter("OrderClause", orderClause, DbType.String),
                    this._db.CreateParameter("WhereClause", whereClause, DbType.String)
                };
            var lst = this._db.Execute("SP_SysFeature_GetList", map, parameters).ToList();
            total = (int)parameters[2].Value;

            return lst;
        }

        public List<SysFeature> GetAllByParentAndProject(int? parentId, EnumProjectType projectType)
        {
            return SysFeatures.Where(m => m.ParentId == parentId && m.ProjectType == projectType).ToList();
        }

        public IQueryable<SysFeature> GetAllRoots()
        {
            return SysFeatures.Where(f => f.ParentId == null);
        }

        public SysFeature GetDetail(int id, bool getInactive = true)
        {
            return SysFeatures.FirstOrDefault(a => a.Id == id && (a.IsActive == true || a.IsActive == !getInactive));
        }

        public int Save(SysFeature detail)
        {
            bool needToSave = false;

            if (detail.Id == -1)
            {
                _context.SysFeatures.Add(detail);
                needToSave = true;
            }
            else
            {
                var dbEntry = GetDetail(detail.Id);
                if (dbEntry != null)
                {
                    dbEntry.Name = detail.Name;
                    dbEntry.Title = detail.Title;
                    dbEntry.Description = detail.Description;
                    dbEntry.Link = detail.Link;
                    dbEntry.Icon = detail.Link;
                    dbEntry.ParentId = detail.ParentId;
                    dbEntry.ProjectType = detail.ProjectType;
                    dbEntry.IsDisplayOnNav = detail.IsDisplayOnNav;
                    dbEntry.DisplayOrder = detail.DisplayOrder;
                    dbEntry.IsActive = detail.IsActive;
                    needToSave = true;
                }
            }

            if (needToSave)
            {
                return this._context.SaveChanges();
            }
            else
            {
                return 0;
            }
        }

        public int UpdateActive(int[] arrId, bool isActive)
        {
            bool needToSave = false;

            foreach (var id in arrId)
            {
                SysFeature dbEntry = GetDetail(id);

                if (dbEntry != null)
                {
                    dbEntry.IsActive = isActive;
                    needToSave = true;
                }
            }

            if (needToSave)
            {
                return _context.SaveChanges();
            }
            else
            {
                return 0;
            }
        }

        public int Delete(int[] arrId)
        {
            bool needSaveChange = false;

            foreach (var id in arrId)
            {
                SysFeature dbEntry = GetDetail(id);
                if (dbEntry != null)
                {
                    _context.SysFeatures.Remove(dbEntry);
                    needSaveChange = true;
                }
            }

            if (needSaveChange)
            {
                return this._context.SaveChanges();
            }
            else
            {
                return 0;
            }
        }
    }
}
